package TXPathFinder;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
import java.awt.Color;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.GraphicsConfigTemplate3D;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.swing.SpinnerNumberModel;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;


/**
*       \class	Viewer
*	\brief	Toute l'interface utilisateur en swing.
**/
public class Viewer extends javax.swing.JFrame
{
    private Canvas3D jCanvas3D;
    private SimpleUniverse universe;
    private OrbitBehavior orbit;
    private BranchGroup BGroom;
    private BranchGroup BGWall;
    private BranchGroup BGgrid;
    private BranchGroup BGGridForSelection;
    private float longueurRoom = 20.0f;
    private float largeurRoom = 20.0f;
    private float hauteurRoom = 2.0f;
    private Shape3D shapeGrille;

    private boolean move;
    private boolean moveCrowd;
    private boolean showGrid;

    /**
     *	\brief	Constructeur
    **/
    public Viewer() throws FileNotFoundException, IOException {
        initCanvas3D();
        initComponents();
        initUniversAndCamera();
        createDecor();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        move = false;
        moveCrowd = false;
        showGrid = false;
    }

    /**
     *	\brief	Accesseur du conteneur du viwer3D
     *  \return Le canvas3D
    **/
    public Canvas3D getjCanvas3D() {
        return jCanvas3D;
    }

    /**
     *	\brief	Ferme le programme C++
    **/
    @Override
     public void finalize()
     {
         DataModel.getInstance().getPf().exit();
     }

    /**
     *	\brief	Crée et initialise tout les composants de l'interface utilisatuer
    **/
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jSeparator3 = new javax.swing.JSeparator();
        jButton1 = new javax.swing.JButton();
        panelColor = new javax.swing.JPanel();
        buttonAddAvatar = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        spinnerX = new javax.swing.JSpinner();
        spinnerY = new javax.swing.JSpinner();
        buttonMove = new javax.swing.JButton();
        buttonShowGrid = new javax.swing.JButton();
        buttonGoto = new javax.swing.JButton();
        modeDebug = new javax.swing.JCheckBox();
        buttonStartCrowd = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        jSeparator4 = new javax.swing.JSeparator();
        jSeparator5 = new javax.swing.JSeparator();
        jLabel5 = new javax.swing.JLabel();
        jSeparator6 = new javax.swing.JSeparator();
        modeDebug1 = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(255, 255, 204));

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabel1.setForeground(new java.awt.Color(0, 0, 102));
        jLabel1.setText("Map");

        jLabel3.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabel3.setForeground(new java.awt.Color(0, 0, 102));
        jLabel3.setText("Agents");

        jButton1.setText("set color");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        panelColor.setBackground(new java.awt.Color(255, 255, 255));
        panelColor.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(102, 153, 255)));
        panelColor.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                panelColorMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout panelColorLayout = new javax.swing.GroupLayout(panelColor);
        panelColor.setLayout(panelColorLayout);
        panelColorLayout.setHorizontalGroup(
            panelColorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 175, Short.MAX_VALUE)
        );
        panelColorLayout.setVerticalGroup(
            panelColorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 56, Short.MAX_VALUE)
        );

        buttonAddAvatar.setText("Add");
        buttonAddAvatar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonAddAvatarActionPerformed(evt);
            }
        });

        jLabel6.setFont(new java.awt.Font("Tahoma", 0, 14));
        jLabel6.setText("Y ");

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 14));
        jLabel7.setText("X");

        spinnerX.setModel(new SpinnerNumberModel(50, 0, 100,1));
        spinnerX.setValue(-1);
        spinnerX.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerXStateChanged(evt);
            }
        });

        spinnerY.setModel(new SpinnerNumberModel(50, 0, 100,1));
        spinnerY.setValue(-1);
        spinnerY.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spinnerYStateChanged(evt);
            }
        });

        buttonMove.setText("Play simulation");
        buttonMove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonMoveActionPerformed(evt);
            }
        });

        buttonShowGrid.setText("Show grid");
        buttonShowGrid.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonShowGridActionPerformed(evt);
            }
        });

        buttonGoto.setText("Go");
        buttonGoto.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonGotoActionPerformed(evt);
            }
        });

        modeDebug.setText("ghosts");
        modeDebug.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modeDebugActionPerformed(evt);
            }
        });

        buttonStartCrowd.setText("Start crowd mode");
        buttonStartCrowd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonStartCrowdActionPerformed(evt);
            }
        });

        jLabel4.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabel4.setForeground(new java.awt.Color(0, 0, 102));
        jLabel4.setText("Actions");

        jLabel5.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabel5.setForeground(new java.awt.Color(0, 0, 102));
        jLabel5.setText("Cognition map");

        modeDebug1.setText("map");
        modeDebug1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                modeDebug1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(771, 771, 771)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(spinnerX, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(spinnerY, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonGoto))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(8, 8, 8)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(buttonStartCrowd, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
                            .addComponent(buttonShowGrid, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
                            .addComponent(buttonMove, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel4)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jSeparator5, javax.swing.GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE))
                            .addComponent(buttonAddAvatar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addGap(2, 2, 2)
                                .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 131, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jSeparator4, javax.swing.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE))
                            .addComponent(panelColor, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(8, 8, 8)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel5)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jSeparator6, javax.swing.GroupLayout.DEFAULT_SIZE, 83, Short.MAX_VALUE))
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(modeDebug1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(modeDebug, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(8, 8, 8)
                        .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, 7, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonShowGrid)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel3)
                    .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 8, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelColor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonAddAvatar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel4)
                    .addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 8, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonMove)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttonStartCrowd)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(buttonGoto)
                    .addComponent(spinnerY, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)
                    .addComponent(spinnerX, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(15, 15, 15)
                        .addComponent(jSeparator6, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel5)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(modeDebug)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(modeDebug1)
                .addContainerGap(314, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     *	\brief	Action sur le bouton qui permet de masquer la grille de la carte
    **/
    /**
     *	\brief	Action sur le bouton qui permet de choisir la couleur de l'avatar
     *  \param  evt Evenement
    **/
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        ChooseColor panelColor = new ChooseColor(this,true,this);
        panelColor.setVisible(true);
    }//GEN-LAST:event_jButton1ActionPerformed

    /**
     *	\brief	Action sur le bouton qui permet d'ajouter un avatar aléatoirement
     *  \param  evt Evenement
    **/
    private void buttonAddAvatarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAddAvatarActionPerformed
       if( !DataModel.getInstance().isFocusTaken() )
            DataModel.getInstance().addAvatar();
        else
            DataModel.getInstance().addAvatarWithHighlight();
    }//GEN-LAST:event_buttonAddAvatarActionPerformed

    /**
     *	\brief	Evenement quand le spinner Y qui permet de définir la position de l'avatar est modifié
     *  \param  evt Evenement
    **/
    private void spinnerYStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerYStateChanged
        int x = Integer.parseInt(spinnerX.getValue().toString());
        int y = Integer.parseInt(spinnerY.getValue().toString());
    }//GEN-LAST:event_spinnerYStateChanged

    /**
     *	\brief	Evenement quand le spinner X qui permet de définir la position de l'avatar est modifié
     *  \param  evt Evenement
    **/
    private void spinnerXStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerXStateChanged
        int x = Integer.parseInt(spinnerX.getValue().toString());
        int y = Integer.parseInt(spinnerY.getValue().toString());
    }//GEN-LAST:event_spinnerXStateChanged

    /**
     *	\brief	Evenement quand le spinner Y qui permet de définir la position de l'avatar est modifié
     *  \param  evt Evenement
    **/
    private void panelColorMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_panelColorMouseClicked
        ChooseColor panelColor = new ChooseColor(this,true,this);
        panelColor.setVisible(true);
    }//GEN-LAST:event_panelColorMouseClicked

    /**
     *	\brief	Bouton qui permet de mettre en mouvement les avatars, ou de les stopper si ils sont déjà en action
     *  \param  evt Evenement
    **/
    private void buttonMoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveActionPerformed
        if( !move )
        {
            buttonMove.setText("Pause simulation");
            DataModel.getInstance().startMove();
            DataModel.getInstance().getPf().run();
            move = true;
        }
        else
        {
            buttonMove.setText("Play simulation");
            DataModel.getInstance().endMove();
            DataModel.getInstance().getPf().stop();
            move = false;
        }
    }//GEN-LAST:event_buttonMoveActionPerformed

    /**
     *	\brief	Action lors du click sur le bouton qui permet de montrer la grille de la carte, ou de la masquer ci celle-ci est éjà visible
     *  \param  evt Evenement
    **/
    private void buttonShowGridActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonShowGridActionPerformed
        if( !showGrid )
        {
            buttonShowGrid.setText("Hide grid");
            shapeGrille.removeAllGeometries();
            shapeGrille.addGeometry(ShapeService.geomGrille((int)longueurRoom,(int)largeurRoom));
            showGrid = true;
        }
        else
        {
            buttonShowGrid.setText("Show grid");
            shapeGrille.removeAllGeometries();
            showGrid = false;
        }
    }//GEN-LAST:event_buttonShowGridActionPerformed


    /**
     *	\brief  Action lors du click sur le bouton Goto (pour indiquer la destionation d'un avatar)
     *  \param  evt Evenement
    **/
	private void buttonGotoActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_buttonGotoActionPerformed
	{//GEN-HEADEREND:event_buttonGotoActionPerformed
            DataModel.getInstance().getPf().goTo((Integer)spinnerY.getValue(),(Integer)spinnerX.getValue());
            /*sendGoto(0,13,6);
            sendGoto(1,35,7);
            sendGoto(2,6,28);
            sendGoto(3,6,56);
            sendGoto(4,4,8);
            sendGoto(5,21,56);
            sendGoto(6,35,25);
            sendGoto(7,35,56);*/
	}//GEN-LAST:event_buttonGotoActionPerformed

        private void sendGoto(int serie,int x, int y)
        {
            for(int i = 0 ; i < 9 ; i++ )
            {
                DataModel.getInstance().getPf().goTo(i+serie*9,x,y);
            }
           /* DataModel.getInstance().getPf().goTo(5+serie*9,x-1,y-1);
            DataModel.getInstance().getPf().goTo(3+serie*9,x-1,y);
            DataModel.getInstance().getPf().goTo(7+serie*9,x-1,y+1);
            DataModel.getInstance().getPf().goTo(1+serie*9,x,y-1);
            DataModel.getInstance().getPf().goTo(0+serie*9,x,y);
            DataModel.getInstance().getPf().goTo(2+serie*9,x,y+1);
            DataModel.getInstance().getPf().goTo(6+serie*9,x+1,y-1);
            DataModel.getInstance().getPf().goTo(4+serie*9,x+1,y);
            DataModel.getInstance().getPf().goTo(8+serie*9,x+1,y+1);*/
        }
        
    /**
     *	\brief  Action lorsque que l'on change de mode (mode debug ou non)
     *  \param  evt Evenement
    **/
        private void modeDebugActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modeDebugActionPerformed
            if( modeDebug.isSelected() )
            {
                DataModel.getInstance().setModeDebug(true);
            }
            else
            {
                DataModel.getInstance().setModeDebug(false);
                DataModel.getInstance().deleteAllGhost();
            }
        }//GEN-LAST:event_modeDebugActionPerformed

        /**
        *	\brief  Action qui permet de bouger une foule d'avatar, ou de la stopper si les avatars sont déjà en mouvement
        *  \param  evt Evenement
        **/
        private void buttonStartCrowdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStartCrowdActionPerformed
            if( !moveCrowd )
            {
                buttonStartCrowd.setText("Stop crowd mode");
                //DataModel.getInstance().startMove();
                DataModel.getInstance().getPf().startCrowd();
                moveCrowd = true;
            }
            else
            {
                buttonStartCrowd.setText("Start crowd mode");
                //DataModel.getInstance().endMove();
                DataModel.getInstance().getPf().stopCrowd();
                moveCrowd = false;
            }
        }//GEN-LAST:event_buttonStartCrowdActionPerformed

        private void modeDebug1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_modeDebug1ActionPerformed
            // TODO add your handling code here:
        }//GEN-LAST:event_modeDebug1ActionPerformed

        
    /**
    /*	\brief	Ajout d'une branche au viewer3D
    /*	\param	bg		La branche à rajouter
    **/
    public void addBranchToUniverse(BranchGroup bg)
    {
        universe.addBranchGraph(bg);
    }

    /**
    /*	\brief	Suppression d'une branche au viewer3D
    /*	\param	bg		La branche à supprimer
    **/
    public void removeBranchToUniverse(BranchGroup bg)
    {
        bg.detach();
    }

    /**
     *	\brief  Permet de définir la couleur courante de l'avatar (la couleur qui sera affecté aux prochains avatars crées)
     *  \param  color Couleur courante
    **/
   public void setCurrentColor(Color color)
   {
        DataModel.getInstance().setCurrentColor(new Color3f(color));
        panelColor.setBackground(color);
   }

   /**
     *	\brief  Set les valeurs des spinners de position des avatars
     *  \param  x Valeur en x
     *  \param  y Valeur en y
    **/
   public void setCoordToSpinner(int x, int y)
   {
        spinnerX.setValue(x);
        spinnerY.setValue(y);
   }

    /**
     *	\brief Initialise la canvas3D (création)
    **/
   private void initCanvas3D()
    {
        GraphicsConfigTemplate3D gCT = new GraphicsConfigTemplate3D();
        GraphicsConfiguration gcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(gCT);

       jCanvas3D = new Canvas3D(gcfg);
       //jCanvas3D.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jCanvas3D, javax.swing.GroupLayout.PREFERRED_SIZE, 750, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(185, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jCanvas3D, javax.swing.GroupLayout.DEFAULT_SIZE, 700, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }

   /**
     *	\brief Initialise l'univers du viewer3D ainsi que les caméras di viewer3D
    **/
    private void initUniversAndCamera() throws FileNotFoundException, IOException
    {
        universe = new SimpleUniverse(jCanvas3D);

        //placement des mur
        BGWall = new BranchGroup();
        File worlMap = new File("..\\magazin.map");
        BGWall = ShapeService.readMap(worlMap.getAbsolutePath());

        longueurRoom = ShapeService.getLongueur();
        largeurRoom = ShapeService.getLargeur();

        BGGridForSelection = new BranchGroup();
        BGGridForSelection = ShapeService.returnGridForSelection();

        // add orbit behavior to ViewingPlatform
        ViewingPlatform viewingPlatform = universe.getViewingPlatform();
        viewingPlatform.setNominalViewingTransform();

        //augmente la profondeur possible de vision
        universe.getViewer().getView().setBackClipDistance(largeurRoom);
        orbit = new OrbitBehavior(jCanvas3D, OrbitBehavior.REVERSE_ALL | OrbitBehavior.STOP_ZOOM);
        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
        orbit.setSchedulingBounds(bounds);
        orbit.setRotationCenter(new Point3d(longueurRoom/2,largeurRoom/2,hauteurRoom/2));
        viewingPlatform.setViewPlatformBehavior(orbit);

        //permet de mettre en highlight des blocs du sol du décor
        PickHighlightBloc pickBeh = new PickHighlightBloc(jCanvas3D, BGGridForSelection, bounds, this);

        //choix de la position par defaut de la camera
        TransformGroup objTrans = universe.getViewingPlatform().getViewPlatformTransform();
        TransformGroup TG = objTrans;
        Transform3D rot=new Transform3D();
        Transform3D rotation=new Transform3D();
        Vector3f translation=new Vector3f();
        TG.getTransform(rotation);
        translation.set(longueurRoom/2,largeurRoom/2,30.0f);
        rot.setTranslation(translation);
        rotation.mul(rot);
        TG.setTransform(rotation);
    }

   /**
     *	\brief Crée le décor en créant les différentes branches qui feront parties de l'univers puis crée la carte de base sans mur à l'interieur
    **/
    private void createDecor() throws FileNotFoundException, IOException
    {
        shapeGrille = new Shape3D();
        shapeGrille.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE | Shape3D.ALLOW_GEOMETRY_READ);

        BGroom = new BranchGroup();
        BGgrid = new BranchGroup();

        BGgrid.addChild(shapeGrille);
        BGgrid.compile();
        universe.addBranchGraph(BGgrid);

        Shape3D shape=ShapeService.housse(longueurRoom,largeurRoom,hauteurRoom,new Color3f(0.9f,0.9f,0.9f));
        BGroom.addChild(shape);

        setLightOfDecor();

        BGroom.compile();
        BGWall.compile();
        BGGridForSelection.compile();
        universe.addBranchGraph(BGroom);
        universe.addBranchGraph(BGWall);
        universe.addBranchGraph(BGGridForSelection);
    }

   /**
     *	\brief Ajoute les lumières a l'univers 3D
    **/
    public void setLightOfDecor()
    {
        //light
        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
        Color3f lightColor = new Color3f(0.6f, 0.6f, 0.8f);

        Vector3f light1Direction = new Vector3f(4.0f, 0.0f, -10.0f);
        DirectionalLight light1 = new DirectionalLight(lightColor, light1Direction);
        light1.setInfluencingBounds(bounds);
        BGroom.addChild(light1);

        Vector3f light1Direction2 = new Vector3f(-2.0f, 0.0f, 10.0f);
        DirectionalLight light2 = new DirectionalLight(lightColor, light1Direction2);
        light2.setInfluencingBounds(bounds);
        BGroom.addChild(light2);

        Vector3f light1Direction3 = new Vector3f(-10.0f, 9.0f, 2.0f);
        DirectionalLight light3 = new DirectionalLight(lightColor, light1Direction3);
        light3.setInfluencingBounds(bounds);
        BGroom.addChild(light3);

        Vector3f light1Direction4 = new Vector3f(8.0f, 0.0f, 0.0f);
        DirectionalLight light4 = new DirectionalLight(lightColor, light1Direction4);
        light4.setInfluencingBounds(bounds);
        BGroom.addChild(light4);

        Color3f lightColor2 = new Color3f(0.6f, 0.1f, 0.1f);
        Vector3f light1Direction5 = new Vector3f(1.0f, -1.0f, 1.0f);
        DirectionalLight light5 = new DirectionalLight(lightColor2, light1Direction5);
        light5.setInfluencingBounds(bounds);
        BGroom.addChild(light5);

        Color3f lightColor3 = new Color3f(0.6f, 0.1f, 0.1f);
        Vector3f light1Direction6 = new Vector3f(-1.0f, 1.0f, -1.0f);
        DirectionalLight light6 = new DirectionalLight(lightColor3, light1Direction6);
        light6.setInfluencingBounds(bounds);
        BGroom.addChild(light6);
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonAddAvatar;
    private javax.swing.JButton buttonGoto;
    private javax.swing.JButton buttonMove;
    private javax.swing.JButton buttonShowGrid;
    private javax.swing.JButton buttonStartCrowd;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JSeparator jSeparator5;
    private javax.swing.JSeparator jSeparator6;
    private javax.swing.JCheckBox modeDebug;
    private javax.swing.JCheckBox modeDebug1;
    private javax.swing.JPanel panelColor;
    private javax.swing.JSpinner spinnerX;
    private javax.swing.JSpinner spinnerY;
    // End of variables declaration//GEN-END:variables

    //private Timer timer;
}
